package com.bjpowernode.crm.workbench.web.controller;

import com.bjpowernode.crm.commons.constants.Constant;
import com.bjpowernode.crm.commons.domain.ReturnObject;
import com.bjpowernode.crm.commons.utils.DateUtils;
import com.bjpowernode.crm.commons.utils.HSSFUtils;
import com.bjpowernode.crm.commons.utils.UUIDUtils;
import com.bjpowernode.crm.settings.domain.User;
import com.bjpowernode.crm.settings.service.UserService;
import com.bjpowernode.crm.workbench.domain.Activity;
import com.bjpowernode.crm.workbench.domain.ActivityRemark;
import com.bjpowernode.crm.workbench.service.ActivityRemarkService;
import com.bjpowernode.crm.workbench.service.ActivityService;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.*;

@Controller
public class ActivityController {

    @Autowired
    private UserService userService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private ActivityRemarkService activityRemarkService;

    @RequestMapping("/workbench/activity/index.do")
    public String index(HttpServletRequest request) {
        //调用service方法查询所有User
        List<User> userList = userService.queryAllUser();
        //将查到的数据保存到request域中
        request.setAttribute("userList", userList);
        //请求跳转到市场活动页面
        return "workbench/activity/index";
    }


    @RequestMapping("/workbench/activity/saveCreateActivity.do")
    @ResponseBody
    public Object saveCreateActivity(Activity activity, HttpSession session) {
        //由于id，创建时间，创建者并不是在网页端创建的，故需要在controller层写出来，并且一起添加到表中
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        //创建id
        activity.setId(UUIDUtils.getUUID());
        //创建时间
        activity.setCreateTime(DateUtils.formateDataTime(new Date()));
        //创建者
        //注意：创建者不能传入创建者的姓名，而是需要创建者的id
        activity.setCreateBy(user.getId());

        ReturnObject returnObject = new ReturnObject();
        //调用service方法保存数据,并且根据结果给用户一个友好提示
        try {
            int resultNum = activityService.saveCreateActivity(activity);
            if (resultNum > 0) {
                //成功
                returnObject.setCode(Constant.RETURN_CODE_SUCCESS);
            } else {
                //失败
                returnObject.setCode(Constant.RETURN_CODE_FAIL);
                returnObject.setMessage("网络开小差去了，请稍后再试...");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_CODE_FAIL);
            returnObject.setMessage("网络开小差去了，请稍后再试...");
        }
        return returnObject;
    }

    @RequestMapping("/workbench/activity/queryActivityByConditionForPage.do")
    @ResponseBody
    public Object queryActivityByConditionForPage(String name, String owner, String startDate, String endDate,
                                                  int pageNo, int pageSize) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("name", name);
        map.put("owner", owner);
        map.put("startDate", startDate);
        map.put("endDate", endDate);
        map.put("beginNo", (pageNo - 1) * pageSize);
        map.put("pageSize", pageSize);

        //使用先前定义好的service
        List<Activity> activityList = activityService.queryActivityByConditionForPage(map);
        int totalRows = activityService.queryCountForActivityByCondition(map);

        //这里再次使用map封装数据是为了将数据传输给前端，在map中的数据会以xx-xx的形式传递这些参数，和json格式一致
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("activityList", activityList);
        resultMap.put("totalRows", totalRows);

        return resultMap;
    }

    @RequestMapping("/workbench/activity/deleteActivityByIds.do")
    @ResponseBody
    public Object deleteActivityByIds(String[] id) {
        ReturnObject returnObject = new ReturnObject();
        try {
            int i = activityService.deleteActivityByIds(id);
            if (i != 0) {
                returnObject.setCode(Constant.RETURN_CODE_SUCCESS);
            } else {
                returnObject.setCode(Constant.RETURN_CODE_FAIL);
                returnObject.setMessage("系统忙请稍后重试！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_CODE_FAIL);
            returnObject.setMessage("系统忙请稍后重试！");
        }
        return returnObject;
    }

    @RequestMapping("/workbench/activity/queryActivityById.do")
    @ResponseBody
    public Object queryActivityById(String id) {
        return activityService.queryActivityById(id);
    }

    @RequestMapping("/workbench/activity/saveUpdateActivity.do")
    @ResponseBody
    public Object saveUpdateActivity(Activity activity, HttpSession session) {
        //封装参数：1.修改的日期
        activity.setEditTime(DateUtils.formateDataTime(new Date()));
        //2.修改者
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        activity.setEditBy(user.getId());
        ReturnObject returnObject = new ReturnObject();
        try {
            int result = activityService.saveUpdateActivity(activity);
            if (result != 0) {
                returnObject.setCode(Constant.RETURN_CODE_SUCCESS);
                returnObject.setMessage("保存修改成功！");
            } else {
                returnObject.setCode(Constant.RETURN_CODE_FAIL);
                returnObject.setMessage("系统忙请稍后重试！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnObject.setCode(Constant.RETURN_CODE_FAIL);
            returnObject.setMessage("系统忙请稍后重试！");
        }
        return returnObject;
    }

    //这是测试文件下载的代码（和本项目功能无关）
    @RequestMapping("/workbench/activity/fileDownload.do")
    //这里返回void是因为，接下来使用下载功能，不使用springMVC，会使用response，request自己输出
    public void fileDownload(HttpServletResponse response) throws Exception {
        //1.设置响应类型；目的是告诉浏览器下载什么文件
        response.setContentType("application/octet-stream;charset=UTF-8");
        //2.获取输出流
        OutputStream os = response.getOutputStream();

        //添加一个响应头，确保文件能够下载，因为如果文件能在浏览器打开，很有可能浏览器第一选择是打开而不是下载
        //同时也规定了下载文件的类型以及格式
        response.addHeader("Content-Disposition", "attachment;filename=mystudentList.xls");


        //3.通过InputStream读入Excel文件
        InputStream is = new FileInputStream("F:\\Java\\HSSWorkBookTest\\testExcel.xls");
        //建立缓冲区
        /**
         * 这段代码实际上就是一个复制文件的过程，使用byte数组是为了提高效率，is读，os写
         */
        byte[] buff = new byte[256];
        int len = 0;
        while ((len = is.read(buff)) != -1) {
            os.write(buff, 0, len);
        }

        //4.关闭流；注意：有一个原则，使用SpringMVC框架后，只有自己new出来的对象才要关闭，
        //使用框架给的则交给框架本身关闭
        is.close();
        //相当于刷新清除缓存
        os.flush();
    }


    //使用response返回数据

    /**
     * 有关优化代码的思路：
     * 由于涉及到内存到磁盘之间的交互，会有运行效率低，不适应高并发的情况；所以我们省略生成文件到磁盘，从磁盘读出文件
     * 这两步，改用直接从内存读再从内存拿，省去磁盘这一交互行为
     */
    //测试用
    @RequestMapping("/workbench/activity/exportAllActivities.do")
    public void exportAllActivities(HttpServletResponse response) throws Exception {
        //调用Service方法
        List<Activity> activityList = activityService.queryAllActivities();

        //1.使用HSSFWorkBook来保存Excel
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("市场活动表");
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell(0);
        cell.setCellValue("ID");
        cell = row.createCell(1);
        cell.setCellValue("所有者");
        cell = row.createCell(2);
        cell.setCellValue("名称");
        cell = row.createCell(3);
        cell.setCellValue("开始日期");
        cell = row.createCell(4);
        cell.setCellValue("结束日期");
        cell = row.createCell(5);
        cell.setCellValue("成本");
        cell = row.createCell(6);
        cell.setCellValue("描述");
        cell = row.createCell(7);
        cell.setCellValue("创建时间");
        cell = row.createCell(8);
        cell.setCellValue("创建者");
        cell = row.createCell(9);
        cell.setCellValue("修改时间");
        cell = row.createCell(10);
        cell.setCellValue("修改者");

        //判断数组是否为空
        if (activityList != null && activityList.size() > 0) {
            //遍历activityList
            Activity activity = null;
            for (int i = 0; i < activityList.size(); i++) {
                //从0开始遍历数组
                activity = activityList.get(i);
                //从第二行开始遍历
                row = sheet.createRow(i + 1);

                cell = row.createCell(0);
                cell.setCellValue(activity.getId());
                cell = row.createCell(1);
                cell.setCellValue(activity.getOwner());
                cell = row.createCell(2);
                cell.setCellValue(activity.getName());
                cell = row.createCell(3);
                cell.setCellValue(activity.getStartDate());
                cell = row.createCell(4);
                cell.setCellValue(activity.getEndDate());
                cell = row.createCell(5);
                cell.setCellValue(activity.getCost());
                cell = row.createCell(6);
                cell.setCellValue(activity.getDescription());
                cell = row.createCell(7);
                cell.setCellValue(activity.getCreateTime());
                cell = row.createCell(8);
                cell.setCellValue(activity.getCreateBy());
                cell = row.createCell(9);
                cell.setCellValue(activity.getEditTime());
                cell = row.createCell(10);
                cell.setCellValue(activity.getEditBy());
            }
        }

        //2.生成excel文件
        /*
        这段代码效率低：使用内存到磁盘，在高并发的情况下，会占用大量内存
        OutputStream os1 = new FileOutputStream("F:\\Java\\HSSWorkBookTest\\activityExcel.xls");
        wb.write(os1);
        os1.close();
        wb.close();
        */

        //3.实现下载功能
        //①设置响应信息
        response.setContentType("application/octet-stream;charset=UTF-8");
        //②获取输出流
        OutputStream os2 = response.getOutputStream();
        //③设置响应头
        response.addHeader("Content-Disposition", "attachment;filename=activityExcel.xls");
        //④建立输入流获取文件信息（下载）
        /*
        这段代码效率低：使用磁盘到内存，在高并发的情况下，会占用大量内存
        InputStream is = new FileInputStream("F:\\Java\\HSSWorkBookTest\\activityExcel.xls");
        //建立缓冲区
        byte[] buff = new byte[256];
        int len = 0;
        while((len=is.read(buff))!=-1){
            os2.write(buff,0,len);
        }
        */
        //具体修改
        wb.write(os2);

        //⑤关闭流
        wb.close();
        os2.flush();
    }

    /**
     * 根据用户选择的数据生成Excel并导出
     * 实现导出功能
     *
     * @param id
     */
    @RequestMapping("/workbench/activity/exportActivitiesById.do")
    public void exportActivitiesById(String[] id, HttpServletResponse response) throws Exception {
        //1.调用service
        List<Activity> activityList = activityService.queryActivitiesById(id);

        //1.使用HSSFWorkBook来保存Excel
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("市场活动表");
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell(0);
        cell.setCellValue("ID");
        cell = row.createCell(1);
        cell.setCellValue("所有者");
        cell = row.createCell(2);
        cell.setCellValue("名称");
        cell = row.createCell(3);
        cell.setCellValue("开始日期");
        cell = row.createCell(4);
        cell.setCellValue("结束日期");
        cell = row.createCell(5);
        cell.setCellValue("成本");
        cell = row.createCell(6);
        cell.setCellValue("描述");
        cell = row.createCell(7);
        cell.setCellValue("创建时间");
        cell = row.createCell(8);
        cell.setCellValue("创建者");
        cell = row.createCell(9);
        cell.setCellValue("修改时间");
        cell = row.createCell(10);
        cell.setCellValue("修改者");

        //判断数组是否为空
        if (activityList != null && activityList.size() > 0) {
            //遍历activityList
            Activity activity = null;
            for (int i = 0; i < activityList.size(); i++) {
                //从0开始遍历数组
                activity = activityList.get(i);
                //从第二行开始遍历
                row = sheet.createRow(i + 1);

                cell = row.createCell(0);
                cell.setCellValue(activity.getId());
                cell = row.createCell(1);
                cell.setCellValue(activity.getOwner());
                cell = row.createCell(2);
                cell.setCellValue(activity.getName());
                cell = row.createCell(3);
                cell.setCellValue(activity.getStartDate());
                cell = row.createCell(4);
                cell.setCellValue(activity.getEndDate());
                cell = row.createCell(5);
                cell.setCellValue(activity.getCost());
                cell = row.createCell(6);
                cell.setCellValue(activity.getDescription());
                cell = row.createCell(7);
                cell.setCellValue(activity.getCreateTime());
                cell = row.createCell(8);
                cell.setCellValue(activity.getCreateBy());
                cell = row.createCell(9);
                cell.setCellValue(activity.getEditTime());
                cell = row.createCell(10);
                cell.setCellValue(activity.getEditBy());
            }
        }

        //3.实现下载功能
        //①设置响应信息
        response.setContentType("application/octet-stream;charset=UTF-8");
        //②获取输出流
        OutputStream os2 = response.getOutputStream();
        //③设置响应头
        response.addHeader("Content-Disposition", "attachment;filename=activityExcel.xls");
        //④建立输入流获取文件信息（下载）
        wb.write(os2);

        //⑤关闭流
        wb.close();
        os2.flush();
    }


    /**
     * 配置springmvc的文件上传解析器(一定要配)
     * 测试用（有错）
     */
    @RequestMapping("/workbench/activity/fileUploadTest.do")
    @ResponseBody
    public Object fileUploadTest(String username, MultipartFile myFile) throws Exception {
        //1.打印出文本信息
        System.out.println("username:" + username);
        //2.上传测试文件（在指定位置生成一个文件）
        //此处一般上传文件的类型不写死
        String originalFilename = myFile.getOriginalFilename();
        File file = new File("F:\\Java\\testFileUpload\\", originalFilename);
        //使用MultipartFile中的方法
        myFile.transferTo(file);

        //返回json（这里的做法是错误的，因为文件上传应该发同步请求，而json只能被ajax解析，也就是异步请求）
        ReturnObject returnObject = new ReturnObject();
        returnObject.setCode(Constant.RETURN_CODE_SUCCESS);
        returnObject.setMessage("上传成功!");
        return returnObject;
    }


    /**
     * 这里会使用异步请求实现上传功能，而测试时使用的是同步请求，故结论是：
     * 下载时只能使用同步请求；但是上传可以使用同步也可以使用异步请求
     *
     * @param activityFile
     * @return
     */
    @RequestMapping("/workbench/activity/importActivity.do")
    @ResponseBody
    public Object importActivity(MultipartFile activityFile, HttpSession session) {
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        ReturnObject returnObject = new ReturnObject();
        //1.将文件保存到服务器磁盘上（注意优化）
        //获取文件类型
        try {
//            String originalFilename = activityFile.getOriginalFilename();
//            File file = new File("F:\\Java\\testFileUpload\\", originalFilename);
//            activityFile.transferTo(file);

            //2.使用apache-io来读出上传的文件
//            InputStream is = new FileInputStream("F:\\Java\\testFileUpload\\" + originalFilename);
            //直接读内存
            InputStream is = activityFile.getInputStream();
            HSSFWorkbook wb = new HSSFWorkbook(is);
            //获取页
            HSSFSheet sheet = wb.getSheetAt(0);
            //获取行
            HSSFRow row = null;
            HSSFCell cell = null;
            Activity activity = null;
            List<Activity> activityList = new ArrayList<Activity>();
            //从第二行打印：打印数据不要表头
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                row = sheet.getRow(i);
                activity = new Activity();
                //id:id无法让用户来写；使用UUID来获取
                activity.setId(UUIDUtils.getUUID());
                /*
                owner:由于这一属性在后台获取的实际是id，但是id又不让用户干涉，那么name就没办法获取到；
                这里采用的方案是直接获取创建者本人的name(当前用户)
                */
                activity.setOwner(user.getId());
                //createTime:创建的时间
                activity.setCreateTime(DateUtils.formateDataTime(new Date()));
                //createBy:创建者
                activity.setCreateBy(user.getId());

                //获取列
                for (int j = 0; j < row.getLastCellNum(); j++) {
                    cell = row.getCell(j);
                    //要进行判断，每个输出数据的属性
                    String cellValue = HSSFUtils.getCellValueForStr(cell);
//                    if(j==0){
//                        activity.setName(cellValue);
//                    }else if(j==1){
//                        activity.setStartDate(cellValue);
//                    }else if(j==2){
//                        activity.setEndDate(cellValue);
//                    }else if(j==3){
//                        activity.setCost(cellValue);
//                    }else if(j==4){
//                        activity.setDescription(cellValue);
//                    }
                    switch (j) {
                        case 0:
                            activity.setName(cellValue);
                        case 1:
                            activity.setStartDate(cellValue);
                        case 2:
                            activity.setEndDate(cellValue);
                        case 3:
                            activity.setCost(cellValue);
                        case 4:
                            activity.setDescription(cellValue);
                    }
                }
                //将数据保存到list中
                activityList.add(activity);
            }
            //调用service方法保存市场活动
            int result = activityService.saveActivityByList(activityList);

            returnObject.setCode(Constant.RETURN_CODE_SUCCESS);
            returnObject.setRetData(result);

        } catch (IOException e) {
            returnObject.setCode(Constant.RETURN_CODE_FAIL);
            returnObject.setMessage("系统忙请稍后再试...");
            e.printStackTrace();
        }
        return returnObject;
    }

    @RequestMapping("/workbench/activity/queryActivityForDetailById.do")
    public String queryActivityForDetailById(String id, HttpServletRequest request) {
        //调用service方法
        Activity activity = activityService.queryActivityForDetailById(id);
        List<ActivityRemark> activityRemarkList = activityRemarkService.queryActivityRemarkForDetailByActivityId(id);

        //使用request保存到域中
        request.setAttribute("activity", activity);
        request.setAttribute("activityRemarkList", activityRemarkList);

        //请求转发
        return "workbench/activity/detail";
    }

}
